package com.GPS_based_training.service;


import com.GPS_based_training.progetto_so2_2014_2015.R;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.widget.Toast;

/**
 * This class implements a service to manage GPS updates
 * @author Danilo Dessi
 *
 */
public class LocationLoggerService extends Service implements LocationListener {
	
	private final IBinder mBinder =  (IBinder) new LocalBinder(); // A binder of this class
	private OnNewGPSPointsListener clientListener; // listener of client
	private LocationManager locationManager; // it is used to connect to GPS of device
	private double latitude; //the latitude that has been detected
	private double longitude; //the longitude that has been detected
	private double speed; //the speed that has been detected
	private boolean stateConnection; //it is used to save the state of connection between GPS and satellites. 
	
	private final int INTERVAL_TIME_UPDATE = 100; //min interval for updates
	private final float INTERVAL_DISTANCE_UPDATE = 0; //min interval for updates
	
	
	@Override
	/**This method creates a service and initializes variables
	 * @author Danilo Dessi'
	 */
	public void onCreate() {
		
		Toast.makeText(this, getString(R.string.connecting_GPS), Toast.LENGTH_SHORT).show();
		
		//initialization of the values
		latitude = 0;
		longitude = 0;
		speed = 0;
		stateConnection = false;
		subscribeToLocationUpdates();
				
	}
	
	@Override
	/**
	 * @author Danilo Dessi'
	 * 
	 * This method deletes a service and disconnects it from GPS updates
	 */
	public void onDestroy() {
		
		super.onDestroy();
		stateConnection = false;
		locationManager.removeUpdates(this);
		Toast.makeText(this,getString(R.string.disconnection_from_the_GPS), Toast.LENGTH_LONG).show();
		
	}
	
	@Override
	/**
	 * @author Danilo Dessi'
	 * 
	 * This method return a binder that allows to client to connects at this service.
	 */
	public IBinder onBind(Intent intent) {
		
		return mBinder;
		
	}
	
	/**
	 * @author Danilo Dessi'
	 * 
	 * This method is used to link the listener
	 * @param listener A listener of client
	 */
	public void addOnNewGPSPointsListener(OnNewGPSPointsListener listener ){
		
		clientListener = listener;
		
	}
	
	/**
	 * @author Danilo Dessi'
	 * 
	 * This method is used to remove listener
	 */
	public void removeOnNewGPSPointsListener() {
	
		clientListener = null;
		
	}
	
	@Override
	/**
	 * @author Danilo Dessi'
	 * This method is used to notify to client for new updates 
	 */
	public void onLocationChanged(Location location) {
		
		// Update informations
		latitude = location.getLatitude();
		longitude = location.getLongitude();
		speed = location.getSpeed();
		
		//we update the state of the GPS
		stateConnection = true;
		
		//we notify client for new updates
		if( clientListener != null ) {
			
			clientListener.onNewGPSPoint();
			
		}
		 
	}
	
	
	@Override
	public void onProviderDisabled(String provider) {
		//not used
	}
	
	
	@Override
	public void onProviderEnabled(String provider) {
		//not used	
	}
	
	
	@Override
	public void onStatusChanged(String provider, int status, Bundle extras) {
		//not used
	}
	
	/**
	 * @author Danilo Dessi'
	 * 
	 * This method waits for incoming updates
	 */
	private void subscribeToLocationUpdates() {
		
		this.locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
		
		//Check GPS enable
		if(!locationManager.isProviderEnabled("gps")) {
			
			Toast.makeText(this, getString(R.string.GPS_inactive), Toast.LENGTH_SHORT).show();
			
		}
				
		//we request updates every second
		this.locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, INTERVAL_TIME_UPDATE, INTERVAL_DISTANCE_UPDATE, this);
		
	}
	
	/**
	 * @author Danilo Dessi'
	 * 
	 * This method return the value of latitude
	 * @return the value of latitude
	 */
	public double getLatitude() {
		
		return latitude;
		
	}
	
	/**
	 * @author Danilo Dessi'
	 * 
	 * This method return the value of longitude
	 * @return the value of longitude
	 */
	public double getLongitude() {
		
		return longitude;
		
	}
	
	/**
	 * @author Danilo Dessi'
	 * 
	 * This method return the value of speed
	 * @return the value of speed
	 */
	public double getSpeed() {
		
		return speed;
		
	}
	
	/**
	 * @author Danilo Dessi'
	 * 
	 * This method is used to return the state of GPS
	 * @return true if the GPS is connected to satellites, false otherwise
	 */
	public boolean getStateConnection() {
	 
		return stateConnection;
	}
	
	/**
	 * @author Danilo Dessi'
	 */
	public class LocalBinder extends Binder{
		
		public LocationLoggerService getService(){
			
			return LocationLoggerService.this;
			
		}
	}
	
	/**
	 * @author Danilo Dessi'
	 * 
	 * Interface for listeners
	 */
	public interface OnNewGPSPointsListener {
		public void onNewGPSPoint();
	}
	
	
}